﻿#include "QUIHelper.h"

#include <QtGui>
#ifdef QT_NETWORK_LIB
#include <QHostAddress>
#endif
#include "MyHelper.h"
#include "CFormCtrl.h"

void QUIHelper::setCenter(QWidget *widget, QWidget *widgetParent)
{
    Q_ASSERT_X(widget, "QUIHelper::setCenter",
               "widget句柄是无效的");
    if (!widget) return;

    if (widgetParent == nullptr) {
        // QRect rect = QApplication::desktop()->availableGeometry();
        // widget->move((rect.width() - widget->width())/2, (rect.height() - widget->height())/2);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
        auto pDeskdop = QGuiApplication::primaryScreen();
        widget->move((pDeskdop->availableGeometry().width() - widget->width())/2, (pDeskdop->availableGeometry().height() - widget->height())/2);
        return;
        QScreen *screen = QGuiApplication::primaryScreen();
        QRect desktop = screen->geometry();
        widget->move((desktop.width() - desktop.width())/2, (desktop.height() - desktop.height())/2);
#else
        QDesktopWidget *desktop = QApplication::desktop();
        widget->move((desktop->width() - widget->width())/2, (desktop->height() - widget->height())/2);
#endif
    } else {
        widget->move(widgetParent->x() + (widgetParent->width() - widget->width())/2, widgetParent->y() + (widgetParent->height() - widget->height())/2);
    }
}

QFont QUIHelper::getIconFont()
{
    auto fontFile = ":/CFormContrl/fontawesome-webfont.ttf";
    if (!QFile::exists(fontFile)) {
#ifdef USING_ONLY_CHINESE
        qCritical().noquote() << "QUIHelper::getIconFont(): 字体库不存在！";
#else
        qCritical().noquote() << QObject::tr("QUIHelper::getIconFont(): FontFile is not exists!");
#endif // USING_ONLY_CHINESE
        return QFont();
    }

    // 引入图形字体
    int fontId = QFontDatabase::addApplicationFont(fontFile);
    QString fontName = QFontDatabase::applicationFontFamilies(fontId).at(0);
    return QFont(fontName);
}

QIcon QUIHelper::getIconColor(const QSize &iconSize, const QColor &color)
{
    QPixmap pixmap(iconSize);
    QPainter painter(&pixmap);
    painter.fillRect(pixmap.rect(), color);
    painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    QIcon colorIcon = QIcon(pixmap);
    return colorIcon;
}

void QUIHelper::setSkinIndex(unsigned int qssIndex)
{
    auto qssList = getSkinInfoList();
    // 皮肤序号超限，取第一款皮肤
    if (qssIndex >= qssList.size()) {
        qssIndex = 0;
    }

    auto skinStr = qssList.at(qssIndex);
    setSkinCode(std::get<0>(skinStr));
}

void QUIHelper::setSkinCode(const QString &qssName)
{
    QStringList qssNameList;
    foreach (auto &item, getSkinInfoList()) {
        qssNameList.append(std::get<0>(item));
    }

    if (qssName.isEmpty() || !qssNameList.contains(qssName)) {
#ifdef USING_ONLY_CHINESE
        CDialog::MessageBoxError("错误", "没有找到皮肤文件，请联系软件开发商@NjGreat.HQH！");
#else
        CDialog::MessageBoxError(QObject::tr("No skin file found, please contact the software developer@NjGreat HQH!"));
#endif // USING_ONLY_CHINESE
        return;
    }

    QString qssFile = QString(":/qssSkinHQH/%1.css").arg(qssName.toLower());
    if (!QFile(qssFile).exists()) {
#ifdef USING_ONLY_CHINESE
        CDialog::MessageBoxError("错误", "皮肤文件已被损坏，请联系软件开发商@NjGreat.HQH！");
#else
        CDialog::MessageBoxError(QObject::tr("The skin file has been damaged, please contact the software developer@NjGreat HQH!"));
#endif // USING_ONLY_CHINESE
        return;
    }

    QFile file(qssFile);
    if (file.open(QFile::ReadOnly)) {
        QString qss = file.readAll();
        QString PaletteColor = qss.mid(20, 7);
        qApp->setPalette(QPalette(QColor(PaletteColor)));
        qApp->setStyleSheet(qss);
        file.close();
    } else {
#ifdef USING_ONLY_CHINESE
        CDialog::MessageBoxError("错误", "皮肤文件打开失败，请联系软件开发商@NjGreat.HQH！");
#else
        CDialog::MessageBoxError(QObject::tr("Skin file opening failed, please contact the software developer@NjGreat HQH!"));
#endif // USING_ONLY_CHINESE
    }
}

QStringList QUIHelper::getSkinCodeList()
{
    QStringList list;
    foreach (auto item, getSkinInfoList()) {
        list.append(std::get<0>(item));
    }
    return list;
}

QStringList QUIHelper::getSkinNameList()
{
    QStringList list;
    foreach (auto item, getSkinInfoList()) {
        list.append(std::get<1>(item));
    }
    return list;
}

QList<std::tuple<QString, QString, QIcon> > QUIHelper::getSkinInfoList()
{
    QSize size(20, 20);
    QList<std::tuple<QString, QString, QIcon> > list {
#ifdef USING_ONLY_CHINESE
        {"Silvery", "银色", getIconColor(size, QColor(225,228,230))},// "#E1E4E6"
        {"Blue", "蓝色", getIconColor(size, QColor(192,211,235))},// "#C0D3EB"
        {"LightBlue", "淡蓝色", getIconColor(size, QColor(222,240,254))},// "#DEF0FE"
        {"DarkBlue", "深蓝色", getIconColor(size, QColor(19,48,80))},// "#133050"
        {"Gray", "灰色", getIconColor(size, QColor(228,228,228))},// "#E4E4E4"
        {"LightGray", "淡灰色", getIconColor(size, QColor(238,238,238))},// "#EEEEEE"
        {"DarkGray", "深灰色", getIconColor(size, QColor(216,217,222))},// "#D8D9DE"
        {"Black", "黑色", getIconColor(size, QColor(77,77,77))},// "#4D4D4D"
        {"LightBlack", "淡黑色", getIconColor(size, QColor(102,116,129))},// "#667481"
        {"DarkBlack", "深黑色", getIconColor(size, QColor(36,38,41))},// "#242629"
        {"PsBlack", "PS黑色", getIconColor(size, QColor(72,72,72))},// "#484848"
        {"FlatBlack", "扁平黑", getIconColor(size, QColor(190,192,194))},// "#BEC0C2"
        {"FlatWhite", "扁平白", getIconColor(size, QColor(228,228,228))}// "#E4E4E4"
#else
        {"Silvery", QObject::tr("Silvery"), getIconColor(size, QColor(225,228,230))},// "#E1E4E6"
        {"Blue", QObject::tr("Blue"), getIconColor(size, QColor(192,211,235))},// "#C0D3EB"
        {"LightBlue", QObject::tr("LightBlue"), getIconColor(size, QColor(222,240,254))},// "#DEF0FE"
        {"DarkBlue", QObject::tr("DarkBlue"), getIconColor(size, QColor(19,48,80))},// "#133050"
        {"Gray", QObject::tr("Gray"), getIconColor(size, QColor(228,228,228))},// "#E4E4E4"
        {"LightGray", QObject::tr("LightGray"), getIconColor(size, QColor(238,238,238))},// "#EEEEEE"
        {"DarkGray", QObject::tr("DarkGray"), getIconColor(size, QColor(216,217,222))},// "#D8D9DE"
        {"Black", QObject::tr("Black"), getIconColor(size, QColor(77,77,77))},// "#4D4D4D"
        {"LightBlack", QObject::tr("LightBlack"), getIconColor(size, QColor(102,116,129))},// "#667481"
        {"DarkBlack", QObject::tr("DarkBlack"), getIconColor(size, QColor(36,38,41))},// "#242629"
        {"PsBlack", QObject::tr("PsBlack"), getIconColor(size, QColor(72,72,72))},// "#484848"
        {"FlatBlack", QObject::tr("FlatBlack"), getIconColor(size, QColor(190,192,194))},// "#BEC0C2"
        {"FlatWhite", QObject::tr("FlatWhite"), getIconColor(size, QColor(228,228,228))}// "#E4E4E4"
#endif
    };
    return list;
}

void QUIHelper::setCtrlErrorStyle(QWidget *widget, bool isOk)
{
    const auto errString = "background-color: red;border:1px solid #e1e0e0;";
    if (widget) {
        auto styleStr = isOk ? widget->styleSheet().remove(errString)
                             : widget->styleSheet().append(errString);
        widget->setStyleSheet(styleStr);
    }
}

void QUIHelper::setTextFormatInt(QLineEdit *text, int bottom, int top)
{
    text->setValidator(new CustomIntValidator(qMin(bottom, top), qMax(bottom, top), text));
}

void QUIHelper::setTextFormatDouble(QLineEdit *text, double bottom, double top, int decimals)
{
    text->setProperty("isDouble", true);
    text->setProperty("decimals", decimals);
    text->setValidator(new CustomDoubleValidator(qMin(bottom, top), qMax(bottom, top), qAbs(decimals), text));
}

void QUIHelper::setTextFormatIPAddress(QLineEdit *text)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    text->setValidator(new QRegularExpressionValidator(QRegularExpression("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$")));
#else
    text->setValidator(new QRegExpValidator(QRegExp("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$")));
#endif
}

void QUIHelper::setTextFormatUserName(QLineEdit *text)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    text->setValidator(new QRegularExpressionValidator(QRegularExpression("^[0-9a-zA-Z_]{1,}$")));
#else
    text->setValidator(new QRegExpValidator(QRegExp("^[0-9a-zA-Z_]{1,}$")));
#endif
}

void QUIHelper::setTextFormatChineseName(QLineEdit *text)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    text->setValidator(new QRegularExpressionValidator(QRegularExpression("[\u4e00-\u9fa5]+$")));
#else
    text->setValidator(new QRegExpValidator(QRegExp("[\u4e00-\u9fa5]+$")));
#endif
}

bool QUIHelper::checkTextFormat(QLineEdit *lineEdit, QString &errString, bool isClear)
{
    bool isOk = true;
    QString text = lineEdit->text();
    if (text.isEmpty()) {
        isOk = false;
#ifdef USING_ONLY_CHINESE
        errString.append(" 输入为空");
#else
        errString.append(QObject::tr(" is a empty string"));
#endif // USING_ONLY_CHINESE
    } else {
        QString objName = lineEdit->objectName().toLower();
        if (objName.endsWith("ip")) {
#ifdef QT_NETWORK_LIB
            QHostAddress ip;
            if (!MyHelper::isIPAddress(text, ip)) {
#else
            if (!MyHelper::isIPAddress(text)) {
#endif
                isOk = false;
#ifdef USING_ONLY_CHINESE
                errString.append(" 不是有效的IP地址");
#else
                errString.append(QObject::tr(" is not a valid IP address"));
#endif // USING_ONLY_CHINESE
            }
        } else if (objName.endsWith("file") || objName.endsWith("filepath")) {
            if (!QFile(text).exists()) {
                isOk = false;
#ifdef USING_ONLY_CHINESE
                errString.append(" 是不存在的文件路径");
#else
                errString.append(QObject::tr(" is not an existing file path"));
#endif // USING_ONLY_CHINESE
            }
        } else if (objName.endsWith("path")) {
            if (!QDir(text).exists()) {
                isOk = false;
#ifdef USING_ONLY_CHINESE
                errString.append(" 是不可访问的路径");
#else
                errString.append(QObject::tr(" is not a reachable path"));
#endif // USING_ONLY_CHINESE
            }
        }
    }

    setCtrlErrorStyle(lineEdit, isOk);
    if (!isOk) {
        if (isClear) {
            lineEdit->clear();
        }
        lineEdit->setFocus();
    }
    return isOk;
}

bool QUIHelper::checkTextIsNum(QLineEdit *lineEdit, QString &errString, bool isClear)
{
    bool isOk = true;
    if (lineEdit->text().isEmpty()) {
        isOk = false;
#ifdef USING_ONLY_CHINESE
        errString.append(" 输入为空");
#else
        errString.append(QObject::tr(" is a empty string"));
#endif // USING_ONLY_CHINESE
    } else {
        if(MyHelper::isNum(lineEdit->text())) {
            isOk = false;
#ifdef USING_ONLY_CHINESE
            errString.append(" 输入非数字");
#else
            errString.append(QObject::tr(" is not a number"));
#endif // USING_ONLY_CHINESE
        }
    }

    setCtrlErrorStyle(lineEdit, isOk);
    if (!isOk) {
        if (isClear) {
            lineEdit->clear();
        }
        lineEdit->setFocus();
    }
    return isOk;
}

void QUIHelper::initTableWidget(QTableWidget *tableWidget, const QStringList &rowHeader)
{
    if (!rowHeader.isEmpty()) {
        tableWidget->setColumnCount(rowHeader.size());
        tableWidget->setHorizontalHeaderLabels(rowHeader);
    }

    // tableWidget->horizontalHeader()->setFixedHeight(35);                     // 设置表头的高度
    // tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);         // 设置不可编辑

    tableWidget->verticalHeader()->setDefaultSectionSize(30);                // 设置行高
    tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);        // 设置选择行为,以行为单位
    tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);       // 设置选择模式,选择单行
    tableWidget->setAlternatingRowColors(true);             // 设置是否交替颜色，默认是false，交替颜色为偶数行为灰色
    // tableWidget->verticalHeader()->setVisible(false);       // 隐藏行表头
    tableWidget->horizontalHeader()->setStretchLastSection(true);   // 最后一列填充

    // 设置水平铺满表格
    // tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
    // 所有列可以手动调整大小
    for (int i = 0; i < tableWidget->columnCount(); ++i) {
        tableWidget->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Interactive);
    }
}

void QUIHelper::setIcon(QWidget *widget, IconCtrlType ctrlType, QChar ch_icon, const QFont &iconFont, quint32 size)
{
    Q_ASSERT(iconFont.pointSize() != -1);
    if (iconFont.pointSize() == -1) {
        return;
    }

    QFont tmpFont = iconFont;
    tmpFont.setPointSize(size);
    widget->setFont(tmpFont);

    if (ctrlType == IconCtrlType::LabelType) {
        qobject_cast<QLabel*>(widget)->setText(ch_icon);
    } else if (ctrlType == IconCtrlType::ButtonType) {
        qobject_cast<QAbstractButton*>(widget)->setText(ch_icon);
    }
}
